/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2013-2014 jfinal app. jfapp Group.
 */

package app.models.member;

import app.Const;
import app.kit.CommonKit;
import app.kit.TypeKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import goja.StringPool;
import goja.annotation.TableBind;
import goja.date.DateFormatter;
import goja.plugins.sqlinxml.SqlKit;
import goja.tuples.Pair;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * The table rlm_account_amount mapping model.
 * </p>
 */
@TableBind(tableName = "rlm_account_amount")
public class AccountAmount extends Model<AccountAmount> {

    /**
     * The public dao.
     */
    public static final AccountAmount dao = new AccountAmount();

    private static final long serialVersionUID = -3728262432605989776L;

    /**
     * 根据账户（会员）id 账户资金记录
     *
     * @param member_id 账户id
     * @return 账户资金记录
     */
    public AccountAmount getAmountByAccount(String member_id) {
        return findFirst(SqlKit.sql("accountamount.getAmountByAccount"), member_id);
    }

    public List<AccountAmount> findByRecord(int page, int memberId) {

        int start = (page - 1) * Const.PAGE;
        int end = start + Const.PAGE;
        return find(SqlKit.sql("accountamount.findByRecord"), memberId, end, start);
    }

    /**
     * 收入总额
     *
     * @param member_id 会员id
     */
    public double sumEarningByMember(String member_id) {
        Record sumEarning = Db.findFirst(SqlKit.sql("accountamount.sumEarningByMember"), member_id);
        Number sumearning = sumEarning.getNumber("sumearning");
        if(null == sumearning){
            return 0;
        }else {
            return sumearning.doubleValue();
        }

    }

    /**
     * 支出总额
     *
     * @param member_id 会员id
     */
    public double sumExpenseByMember(String member_id) {
        Record sumExpense = Db.findFirst(SqlKit.sql("accountamount.sumExpenseByMember"), member_id);
        Number sumexpense = sumExpense.getNumber("sumexpense");
        if(null == sumexpense){
            return 0;
        }else{
            return sumexpense.doubleValue();
        }
    }

    /**
     * 创建支出记录
     *
     * @param memberId    会员ID
     * @param productName 产品名称
     * @param resp_date   业务日期
     * @param amount      金额
     * @return 支出记录
     */
    public AccountAmount buyExpense(int memberId, String productName, DateTime resp_date, BigDecimal amount) {
        return createAccountAmount(memberId, resp_date, amount, "购买产品[" + productName + "]");
    }

    /**
     * 创建收益支出记录
     *
     * @param memberId    会员ID
     * @param productName 产品名称
     * @param resp_date   业务日期
     * @param amount      金额
     * @return 支出记录
     */
    public AccountAmount profitExpense(int memberId, String productName, DateTime resp_date, BigDecimal amount) {
        return createAccountAmount(memberId, resp_date, amount, "产品[" + productName + "]到期发放收益");
    }


    private AccountAmount createAccountAmount(int memberId,  DateTime resp_date, BigDecimal amount, String value) {
        final AccountAmount accountAmount = new AccountAmount();
        accountAmount.set(Const.FIELD_MEMBER, memberId);
        accountAmount.set(Const.FIELD_NAME, value);
        accountAmount.set("record_year", resp_date.getYear());
        accountAmount.set("record_month", resp_date.getMonthOfYear());
        accountAmount.set("record_day", resp_date.getDayOfMonth());
        accountAmount.set("record_time", resp_date);
        accountAmount.set("expense", amount);
        accountAmount.set(Const.FIELD_CREATE_TIME, DateTime.now());
        return accountAmount;
    }
    /**
     * 创建支出记录
     *
     * @param memberId    会员ID
     * @param productName 产品名称
     * @param resp_date   业务日期
     * @param amount      金额
     * @return 支出记录
     */
    public AccountAmount failExpense(int memberId, String productName, DateTime resp_date, BigDecimal amount) {
        return earning(memberId, "产品[" + productName + "]募集失败返回金额", resp_date, amount);
    }


    /**
     * 创建转让支出记录
     *
     * @param memberId    会员ID
     * @param productName 产品名称
     * @param resp_date   业务日期
     * @param amount      金额
     * @return 支出记录
     */
    public AccountAmount transfer_expense(int memberId, String productName, DateTime resp_date, BigDecimal amount) {
        final AccountAmount accountAmount = new AccountAmount();
        accountAmount.set(Const.FIELD_MEMBER, memberId);
        accountAmount.set(Const.FIELD_NAME, "购买转让产品[" + productName + "]");
        accountAmount.set("record_year", resp_date.getYear());
        accountAmount.set("record_month", resp_date.getMonthOfYear());
        accountAmount.set("record_day", resp_date.getDayOfMonth());
        accountAmount.set("record_time", resp_date);
        accountAmount.set("expense", amount);
        accountAmount.set("pay_type", "电子账户");
        accountAmount.set(Const.FIELD_CREATE_TIME, DateTime.now());
        return accountAmount;
    }


    /**
     * 创建收益发放本金收入记录
     *
     * @param memberId    会员ID 61
     * @param productName 产品名称
     * @param resp_date   业务日期
     * @param amount      金额
     * @return 支出记录
     */
    public AccountAmount profitPaid(int memberId, String productName, DateTime resp_date, BigDecimal amount) {
        return earning(memberId, "产品[" + productName + "]到期本金退还", resp_date, amount);
    }


    /**
     * 创建收入记录
     *
     * @param memberId  会员ID
     * @param desc      收入描述
     * @param resp_date 业务日期
     * @param amount    金额
     * @return 支出记录
     */
    public AccountAmount earning(int memberId, String desc, DateTime resp_date, BigDecimal amount) {
        final AccountAmount accountAmount = new AccountAmount();
        accountAmount.set(Const.FIELD_MEMBER, memberId);
        accountAmount.set(Const.FIELD_NAME, desc);
        accountAmount.set("record_year", resp_date.getYear());
        accountAmount.set("record_month", resp_date.getMonthOfYear());
        accountAmount.set("record_day", resp_date.getDayOfMonth());
        accountAmount.set("record_time", resp_date);
        accountAmount.set("earning", amount);
        accountAmount.set(Const.FIELD_CREATE_TIME, DateTime.now());
        return accountAmount;
    }


    /**
     * 同过会员，时间类型，分页，类型查询帐号记录
     *
     * @param memberId 会员ID
     * @param timeType 1：三个月，2：半年
     * @param page     当前页
     * @param pageSize 分页大小
     * @param type     0：表示全部，1：表示支出，2：收入
     *                 timeType 1：三个月，2：半年
     *                 type 0：表示全部，1：表示支出，2：收入
     */
    public Page<AccountAmount> findByMemerbTimeType(int memberId, int timeType, int page, int pageSize, int type) {
        Pair<Integer, Integer> offsets = CommonKit.pageOffset(page, pageSize);
        DateTime now = DateTime.now();
        DateTime month_time;
        int total = 0;
        int totalPage;
        List<AccountAmount> accountAmounts = null;
        month_time = now.plusMonths((timeType == 1) ? -3 : -6);
        String lastT = month_time.toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS);
        String countSql = SqlKit.sql("accountamount.findCountByMemerbTimeType");
        String memberTimeSql = SqlKit.sql("accountamount.findByMemerbTimeType");
        AccountAmount accountAmount;
        switch (type) {
            case 0:
                accountAmount = findFirst(String.format(countSql, StringPool.EMPTY), memberId, lastT);
                total = TypeKit.getInt(accountAmount, Const.FIELD_CNT);
                accountAmounts = find(String.format(memberTimeSql, StringPool.EMPTY), memberId, lastT, offsets.getValue1(), offsets.getValue0());
                break;
            case 1:
                accountAmount = findFirst(String.format(countSql, " AND earning=?"), memberId, lastT, 0);
                total = TypeKit.getInt(accountAmount, Const.FIELD_CNT);
                accountAmounts = find(String.format(memberTimeSql, " AND earning=?"), memberId, lastT, 0, offsets.getValue1(), offsets.getValue0());
                break;
            case 2:
                accountAmount = findFirst(String.format(countSql, " AND expense=?"), memberId, lastT, 0);
                total = TypeKit.getInt(accountAmount, Const.FIELD_CNT);
                accountAmounts = find(String.format(memberTimeSql, " AND expense=?"), memberId, lastT, 0, offsets.getValue1(), offsets.getValue0());
                break;
        }
        if (total % pageSize != 0) {
            totalPage = total / pageSize + 1;
        } else {
            totalPage = total / pageSize;
        }
        return new Page<AccountAmount>(accountAmounts,page,pageSize,totalPage,total);
    }
}